<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
    <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
    <META HTTP-EQUIV="Expires" CONTENT="0">
    <title>CSS示例</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
        list-style: none;
        box-sizing: border-box;
    }
    :root{
        --bg-color-light: #fff2;
        --bg-color: #fff5;
        --color: #fff;
        --scroll-thumb-color: #fffa;
    }
    body{
        overflow: hidden;
        background-color: black;
    }
    .directory{ 
        position: absolute;
        width: 250px;
        left: 10px;
        top: 10px;
        height: 400px;
        border-radius: 10px;
        overflow: hidden;
        padding-right: 10px;
        background: var(--bg-color-light);
        display: flex;
        flex-direction: column;
        z-index: 1;
    }

    .obj{
        position: absolute;
        width: 100vw;
        height: 100vh;
        z-index: -1;
    }
    .scrollbox{
        flex: 1;
        width: 100%;
        overflow: hidden;
    }
    .item-binding{
        height: 40px;
        background-color: var(--bg-color);
        border-radius: 10px;
        margin: 0 10px 10px 10px;
        padding: 10px;
        color: var(--color);
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        display: flex;
    }
    .scrollbar{
        height: calc(100% - 30px);
        width: 10px;
        background: var(--bg-color);
        border-radius: 5px;
        position: absolute;
        right: 0;
        top: 0;
        margin: 10px 4px 20px 0;
    }
    .thumb{
        width: 10px;
        height: 20px;
        background: var(--scroll-thumb-color);
        border-radius: 5px;
    }
    .resizeBtn{
        float: right;
        color: transparent;
        width: 14px;
        height: 14px;
        background: linear-gradient(to right bottom,transparent 40%,var(--color) );
        border-radius: 8px;
        position: absolute;
        right: 3px;
        bottom: 3px;
        cursor: se-resize;
    }
    .resizeBtn:hover{
        background: linear-gradient(to right bottom,transparent 40%,var(--scroll-thumb-color) 0);
    }
    .cover{
        position: absolute;
        width: 100vw;
        height: 100vh;
        visibility: hidden;
    }
    .titleBar{
        height: 32px;
        display: flex;
        margin: 10px;
        min-width: 32px;
        overflow: hidden;
    }
    .titleBtn{
        background-color: var(--bg-color);
        border-radius: 10px;
        width: 32px;
        min-width: 32px;
        line-height: 32px;
        text-align: center;
        color: var(--color);
    }
    .themeBtn{
        margin-right: 2px;
    }
    .titleName{
        flex: 1;
        min-width: 100px;
        color: var(--color);
        text-align: center;
        line-height: 32px;
    }
    .item-folder::before,.item-demo::before{
        width: 20px;
        height: 20px;
        display: block;
        margin-right: 8px;
    }
    .item-folder::before{
        content: "";
        background-color: var(--color);
        border-radius: 50%;
    }
    .item-demo::before{
        content: "#";
        border-radius: 5px;
        background-color: var(--bg-color);
        text-align: center;
        min-width: 20px;
    }
    @keyframes openNewPage {
        0%{
            background-color: #0000;
        }
        33%{
            background-color: #111;
        }
        66%{
            background-color: #111;
        }
        100%{
            background-color: #0000;
        }
    }
    .animation{
        animation-name: openNewPage;
        animation-duration: 0.5s;
    }
    .link{
        position: absolute;
        bottom: 10px;
        text-align: center;
        width: 100%;
        line-height: 22px;
        padding-right: 122px;
    }
    .link:hover +.detailBox{
        opacity: 1;
    }
    .detailBox{
        transition: all 0.5s linear;
        position: absolute;
        left: 0;
        right: 0;
        bottom: 32px;
        margin: 0 10px;
        /* visibility: hidden; */
        opacity: 0;
        text-align: center;
        background-color: var(--bg-color-light);
        color: var(--color);
        border-radius: 10px;
        padding: 2px 10px;
        pointer-events: none;
    }
    .detailBox label{
        text-align: left;
        display: inline-block;
        vertical-align: middle;
        font-size: 0.6rem;
    }
    a{
        color: var(--scroll-thumb-color);
    }
    .share,.shared{
        position: absolute;
        margin-left: 10px;
        transition: .3s;
    }
</style>
<body>
    <div class="cover"></div>
    <div class="directory">
        <div class="titleBar">
            <div class="titleBtn" onclick="handleHome()">H</div>
            <div class="titleName"></div>
            <div class="titleBtn themeBtn" onclick="handleTheme()">D</div>
            <div class="titleBtn" onclick="handleBack()">B</div>
        </div>
        <div class="scrollbox">
            <div class="item-binding"></div>
        </div>
        <div class="scrollbar">
            <div class="thumb"></div>
        </div>
        <div class="resizeBtn"></div>
    </div>
    <div class="link">
        <a href="https://gitee.com/guhunjun/css-style/tree/master/example/CSS特效/彩带时钟" target="_blank" class="git">Gitee地址</a>
        <a href="https://www.bilibili.com/video/BV1n8411n7M3" target="_blank" class="source">来源地址</a>
        <a href="./example/CSS特效/彩带时钟/index.html" target="_blank" class="newPage">新页面打开</a>
        <a class="shared" style="opacity: 0;">已复制到剪切板</a>
        <a href="javascript:void(0)" class="share" onclick="handleShare()">点击我进行分享</a>
    </div>
    <div class="detailBox">
        <label>
            来源：【bilibili视频】彩带时钟<br>
            作者：前端Benny_文华星启<br>
            重现时间：2023年02月01日
        </label>
    </div>
    <object class="obj" name="obj" data="#" type=""></object>
</body>

<script>
    let itemBox = document.querySelector(".scrollbox");
    let itemTemplate = document.querySelector(".item-binding").cloneNode(true);
    let cover = document.querySelector(".cover");
    let url = [];
    let tree = null;
    let detail = null;
    let darkTheme = false;  // 设置深色主题
    let selfTheme = null;
    let defaultUrl = ["CSS特效","彩带时钟"];
    openJson("./myConfig.json",(res)=>{
        tree = res.tree;
        let version = res.version;
        if(localStorage["version"] < version){
            // 版本发生更新，弹出更新内容
        }
        localStorage["version"] = version;
        // 如果带参访问
        let loc = decodeURIComponent(window.location.search);
        if(loc){
            showItem(loc.slice(1).split("/"));
            url = loc.slice(1).split("/").slice(0,-1);
        }else{
            // 上次访问的路径
            if(localStorage["historyFolder"] && localStorage["historyFolder"]!="")
                url = localStorage["historyFolder"].split("/");
            // 上次访问的页面
            if(localStorage["historyPage"])
                showItem(localStorage["historyPage"].split("/"));
            else
                //默认页面
                showItem(defaultUrl);
        }
        openFolder(url,tree);
    })

    function handleBack(){
        url.pop();
        openFolder(url,tree);
    }

    function handleHome(){
        url = [];
        openFolder(url,tree);
    }

    function handleTheme(arg){
        if(arg == null){
            // 主题切换
            if(selfTheme!=null){
                if(darkTheme == false){
                    darkTheme = true
                }else if(darkTheme == true){
                    handleTheme(selfTheme);
                    return;
                }else if(darkTheme == null){
                    darkTheme = false
                }
            }else{
                darkTheme = !darkTheme;
            }
        }
        if(arg?.dark != null){
            darkTheme = arg.dark;
        }
        let args = {bglight:null,bgcolor:null,color:null,thumb:null,inner:null};
        if(darkTheme != false){
            args.bglight = '#0006';
            args.bgcolor = '#0007';
            args.thumb = '#000a';
            args.inner = selfTheme!=null?"S":"L";
        }else{
            args.bglight = '#fff2';
            args.bgcolor = '#fff5';
            args.thumb = '#fffa';
            args.inner = "D";
        }
        if(arg?.bglight)
            args.bglight = arg.bglight;
        if(arg?.bgcolor)
            args.bgcolor = arg.bgcolor;
        if(arg?.color)
            args.color = arg.color;
        if(arg?.thumb)
            args.thumb = arg.thumb;
        if(arg?.bglight || arg?.bgcolor || arg?.color || arg?.thumb){
            args.inner = "L";
            selfTheme = args;
            darkTheme = null;
        }
        document.documentElement.style.setProperty('--bg-color-light',args.bglight);
        document.documentElement.style.setProperty('--bg-color',args.bgcolor);
        if(args.color)
            document.documentElement.style.setProperty('--color',args.color);
        document.documentElement.style.setProperty('--scroll-thumb-color',args.thumb);
        document.querySelector(".themeBtn").innerHTML = args.inner;
    }
    
    function handleShare(){
        let transfer = document.createElement('input');
        transfer.style.display = "hidden";
        document.body.appendChild(transfer);
        // transfer.value = decodeURIComponent(window.location.href);  // 这里表示想要复制的内容
        transfer.value = decodeURIComponent(window.location.search).slice(1) + "：\n" + location.href;
        transfer.focus();
        transfer.select();
        if (document.execCommand('copy')) {
            document.execCommand('copy');
        }
        transfer.blur();
        document.body.removeChild(transfer);
        document.querySelector(".share").style.opacity = "0";
        document.querySelector(".shared").style.opacity = "1";
        setTimeout(()=>{
            document.querySelector(".shared").style.opacity = "0";
            document.querySelector(".share").style.opacity = "1";
        },1000);
    }
    // 打开json文件，func获取内容
    function openJson(url,func){
        let req = new XMLHttpRequest();
        req.open("get",url);
        req.send();
        req.onload = () => {
            if(req.status == 200){
                func(JSON.parse(req.response));
            }else{
                func(null);
            }
        }
    }
    
    // 根据详情信息渲染界面
    function openFolder(url,tree){
        let littleTree = tree;
        for(let i in url){
            for(let j in littleTree){
                if(i==url.length-1 && littleTree[j]==url[i]){
                    showItem(url);
                    return;
                }
                if(littleTree[j]?.name == url[i]){
                    littleTree = littleTree[j].children;
                    break;
                }
                // 不存在节点
                if(j==littleTree.length-1){
                    handleHome();
                    return;
                }
            }
        }
        // 保存当前访问路径
        localStorage["historyFolder"] = url.join("/")
        // title显示内容
        if(url.length>0){
            document.querySelector(".titleName").innerHTML = url[url.length - 1];
        }else{
            document.querySelector(".titleName").innerHTML = "Home";
        }
        // 生成列表清单
        let itemFolder = [];
        let itemDemo = [];
        for(let i of littleTree){
            if(i.name){
                itemFolder.push(i.name)
            }else{
                itemDemo.push(i);
            }
        }
        while(itemBox.children.length){
            itemBox.children[0].remove()
        }
        for(let i of itemFolder){
            let divG = itemTemplate.cloneNode(true);
            divG.innerHTML = i
            divG.addEventListener("click",()=>{
                itemOnClick(i)
            });
            divG.classList.add("item-folder");
            itemBox.appendChild(divG)
        }
        for(let i of itemDemo){
            let divG = itemTemplate.cloneNode(true);
            divG.innerHTML = i
            divG.addEventListener("click",()=>{
                itemOnClick(i)
            });
            divG.classList.add("item-demo");
            itemBox.appendChild(divG)
        }
        if(itemDemo.length+itemFolder.length <= 0){
            let label = document.createElement("div");
            label.style.color = "var(--scroll-thumb-color)";
            label.style.textAlign = "center";
            label.style.marginTop = "16px"
            label.innerHTML = "咩有内容捏o(╥﹏╥)o"
            itemBox.appendChild(label);
        }
        function itemOnClick(name){
            url.push(name);
            openFolder(url,tree);
        }
    }
    
    // 打开具体项目
    function showItem(url){
        if(cover.lock){
            // alert("点击过快，按钮起火了QAQ")
            url.pop();
            return
        }
        // 判断该路径是否正确
        let lTree = tree;
        for(let i in url){
            for(let j in lTree){
                if(lTree[j]?.name == url[i]){
                    lTree = lTree[j].children;
                    break;
                }
                if(i==url.length-1 && lTree[j] == url[i]){
                    break
                }
                // 没找到
                if(j==lTree.length-1){
                    showItem(defaultUrl);
                    return;
                }
            }
        }
        window.history.pushState({}, 0,  window.location.href.split("?")[0] + '?' + url.join("/"));
        // 保存上次访问的页面
        localStorage["historyPage"] = url.join("/");
        cover.style.visibility = "visible";
        cover.lock = true;
        cover.classList.add("animation");
        openJson(`./example/${url.join('/')}/detail.json`,(res)=>{
            detail = res;
        })
        setTimeout(()=>{
            cover.classList.remove("animation");
            cover.style.visibility = "hidden";
            cover.lock = false;
        },500)
        setTimeout(()=>{
            if(cover.lock){
                obj.open(`./example/${url.join('/')}/index.html`,'_self');
            }
            // 其他变化
            selfTheme = null;
            if(detail?.color){
                handleTheme(detail.color);
            }else{
                handleTheme({dark:false});
            }
            document.querySelector(".git").href = `https://gitee.com/guhunjun/css-style/tree/master/example/${url.join('/')}`;
            document.querySelector(".detailBox label").innerHTML = `
            来源：${detail.source.title}<br>
            作者：${detail.source.author}<br>
            重现时间：${detail.time}
            `;
            document.querySelector(".source").href = detail.source.url;
            document.querySelector(".newPage").href = `${window.location.href.split("/?")[0]}/example/${url.join('/')}/index.html`;
            url.pop();
        },200)
    }
    // 页面加载完成
    window.onload = function(){
        // 滚动效果
        let scrollbar = document.querySelector(".scrollbar");
        let scrollbox = document.querySelector(".scrollbox");
        let container = scrollbar.parentNode;
        let thumb = document.querySelector(".thumb");
        let resizeBtn = document.querySelector(".resizeBtn");
        let maxTop;
        let ratio;
        let prevY = null;
        let resizing = null;
        onResize()
        container.addEventListener('mousewheel', function(e) {
            scrollbox.scrollTop += e.deltaY;
            onScroll();
        },{passive: true});
        window.addEventListener('mousedown',function(e){
            if(cover.lock){
                return
            }
            if(e.target === thumb){
                prevY = e.pageY;
            }
            if(e.target === resizeBtn){
                resizing = [e.offsetX,e.offsetY];
            }
            cover.style.visibility = "visible";
        })
        window.addEventListener('mouseup',function(e){
            if(cover.lock){
                return
            }
            prevY = null;
            resizing = null
            cover.style.visibility = "hidden";
        })
        window.addEventListener('mousemove',function(e){
            if(prevY){
                scrollbox.scrollTop += (e.pageY - prevY) * ratio;
                let translateY = scrollbox.scrollTop / ratio;
                onScroll();
                prevY = e.pageY;
            }
            if(resizing){
                if(!resizeBtn.right){
                    resizeBtn.right = parseInt(getComputedStyle(resizeBtn).right);
                    container.left = parseInt(getComputedStyle(container).left);
                    resizeBtn.bottom = parseInt(getComputedStyle(resizeBtn).bottom);
                    container.top = parseInt(getComputedStyle(container).top);
                }
                let width = e.clientX + resizeBtn.offsetWidth - resizing[0] + resizeBtn.right - container.left;
                let height = e.clientY + resizeBtn.offsetHeight - resizing[1] + resizeBtn.bottom - container.top;
                // 70 60
                let minWidth = 60;
                let minHeight = 52;
                let maxWidth = window.innerWidth - container.left;
                let maxHeight = window.innerHeight - container.top;
                width = width < minWidth ? minWidth:width;
                height = height < minHeight ? minHeight:height;
                width = width > maxWidth ? maxWidth:width;
                height = height > maxHeight ? maxHeight:height;
                if(width!=minWidth || height!=minHeight){
                    onResize();
                }
                container.style.width = width + "px";
                container.style.height = height + "px";
            }
            e.preventDefault();
        })
        
        function onResize(){
            maxTop = scrollbox.scrollHeight - scrollbox.offsetHeight;
            if(maxTop<=0){
                scrollbar.style.visibility = "hidden";
                return;
            }else{
                scrollbar.style.visibility = "visible";
            }
            // 设置滑块高度
            thumb.style.height = scrollbar.offsetHeight * (scrollbox.offsetHeight / scrollbox.scrollHeight) + "px";
            // 滑动比率
            ratio = (scrollbox.scrollHeight - scrollbox.offsetHeight) / (scrollbar.offsetHeight - thumb.offsetHeight);
            onScroll();
        }
        function onScroll(){
            let translateY = scrollbox.scrollTop / ratio;
            if(translateY + thumb.offsetHeight > scrollbar.offsetHeight){
                scrollbox.scrollTop = maxTop;
                translateY = scrollbox.scrollTop / ratio;
            }
            thumb.style.transform = "translate(0, "+ translateY  +"px)";
        }
    }
</script>
</html>